package com.currency.service.impl;

import cn.hutool.core.util.IdUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.currency.exception.AppException;
import com.currency.mapper.*;
import com.currency.pojo.*;
import com.currency.request.*;
import com.currency.response.BaseResponse;
import com.currency.response.NormalResponse;
import com.currency.response.QueryCoinsListResponse;
import com.currency.service.CoinsService;
import com.currency.service.PayService;
import io.swagger.annotations.ApiOperation;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;

import java.math.BigDecimal;
import java.util.List;
import java.util.Map;

@Service("coinsService")
public class CoinsServiceImpl  implements CoinsService {
    @Autowired
    private PayService payService;

    @Autowired
    private WytPrePayOrderMapper prePayOrderMapper;

    @Autowired
    private CoinsFreezeMapper coinsFreezeMapper;

    @Autowired
    private WytAdvancePaymentMapper wytAdvancePaymentMapper;

    @Autowired
    private NormalMapper normalMapper;

    @Autowired
    private PayAccountMapper payAccountMapper;

    @Autowired
    private WytOilCardOfflineWithdrawalMapper oilCardOfflineWithdrawalMapper;

    @Value("${sys.certPath}")
    private String certPath;

    @PostMapping("/freeze")
    @ApiOperation(value = "冻结金币接口")
    public BaseResponse freeze(@RequestBody @Validated FreezeCoinsRequest request) throws Exception {
        return payService.freezeUserCoins(request);
    }

    @PostMapping("/unfreeze")
    @ApiOperation(value = "解冻金币接口  unFreezeType 的值区分返还还是转移 trans - 金币转移    back -  金币退回解冻 ")
    public BaseResponse unfreeze(@RequestBody @Validated TransUserCoinsRequest request) throws Exception {
        return payService.transUserCoins(request);
    }

    @GetMapping("/list")
    @ApiOperation(value = "金币交易流水记录查询   coinsType: yuan - 元  fen - 分")
    public QueryCoinsListResponse coinsList(String userId, String month, String coinsType) throws Exception {
        return payService.coinsList(userId, month, coinsType);
    }

    @PostMapping("/prepay")
    @ApiOperation(value = "申请结算付款")
    public BaseResponse prePay(@RequestBody PrePayRequest request) throws AppException {
        return payService.prePay(request);
    }

    @PostMapping("/query-prepay")
    @ApiOperation(value = "查询结算信息")
    public NormalResponse queryPrepay(@RequestBody QueryPrepayRequest request) throws AppException {
        QueryWrapper<WytPrePayOrderPojo> queryWrapper = new QueryWrapper<>();
        if (StringUtils.isNotBlank(request.getOrderId())) {
            queryWrapper.eq("order_id", request.getOrderId());
        } else if (StringUtils.isNotBlank(request.getWaybillId())) {
            queryWrapper.eq("waybill_id", request.getWaybillId());
        } else {
            throw new AppException("cey9999", "运单ID和货源ID 不可全部为空");
        }
        WytPrePayOrderPojo pojo = prePayOrderMapper.selectOne(queryWrapper);
        return NormalResponse.success(pojo);
    }

    @PostMapping("add-exp-prepay")
    @ApiOperation(value = "增加结算订单额外费用")
    public BaseResponse addExtFee(@RequestBody AddExtFeeRequest request) throws AppException {
        return payService.addExtFee(request);
    }

    @GetMapping("/ensure-prepay")
    @ApiOperation(value = "结算付款通过，打款给司机")
    public BaseResponse ensurePrePay(String prePayId) throws Exception {
        return payService.ensurePrePay(prePayId);
    }

    @GetMapping("/hasten-prepay")
    @ApiOperation(value = "催促审核结算付款")
    public BaseResponse hastenPrepay(String prePayId) throws AppException {
        WytPrePayOrderPojo pojo = prePayOrderMapper.selectById(prePayId);
        if (pojo == null) {
            throw new AppException("cey9998", "未查询到对应的预付款");
        }
        pojo.setHastenCnt(pojo.getHastenCnt() + 1);
        prePayOrderMapper.updateById(pojo);
        return new BaseResponse("cey0000", "催促审核付款成功");
    }

    @PostMapping("/freeze-coins-page")
    @ApiOperation(value = "查询冻结记录")
    public NormalResponse<List<WytCurrencyCoinsFreeze>> freezeCoinsPage(@RequestBody UserIdNormalRequest request) throws AppException {
        if (StringUtils.isBlank(request.getUserId())) {
            throw new AppException("cey9999", "用户id不能为空");
        }
        Page<WytCurrencyCoinsFreeze> page = new Page<>();
        page.setSize(request.getPageSize());
        page.setPages(request.getPage());
        QueryWrapper<WytCurrencyCoinsFreeze> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("user_id", request.getUserId());
        Page<WytCurrencyCoinsFreeze> pageData = coinsFreezeMapper.selectPage(page, queryWrapper);

        return NormalResponse.success(pageData.getRecords());
    }

    @PostMapping("/query-advance-payment")
    @ApiOperation(value = "提前付款查询接口")
    public NormalResponse<List<WytAdvancePayment>> queryAdvancePayment(@RequestBody UserIdNormalRequest request) {
        Page<WytAdvancePayment> page = new Page<>();
        page.setSize(request.getPageSize());
        page.setPages(request.getPage());
        QueryWrapper<WytAdvancePayment> wrapper = new QueryWrapper<>();
        wrapper.eq("driver_id", request.getUserId());
        if (StringUtils.isNotBlank(request.getOrderId())) {
            wrapper.eq("order_id", request.getOrderId());
        }
        page = wytAdvancePaymentMapper.selectPage(page, wrapper);
        NormalResponse<List<WytAdvancePayment>> response = new NormalResponse<>();
        response.setErrCode("cey0000");
        response.setErrMsg("查询完成");
        response.setData(page.getRecords());
        return response;

    }

    @PostMapping("/advance-payment")
    @ApiOperation(value = "提前付款申请接口")
    public BaseResponse advancePayment(@RequestBody AdvancePaymentRequest request) throws AppException {
        Map<String, Object> orderMap = normalMapper.queryOrder(request.getOrderId());
        if (orderMap == null || orderMap.get("id") == null) {
            throw new AppException("cey9999", "运单ID不存在");
        }

        if (!StringUtils.equalsIgnoreCase(request.getDriverId(), orderMap.get("driver_id").toString())) {
            throw new AppException("cey9999", "实际接单用户与运单id不匹配");
        }
        WytAdvancePayment payment = new WytAdvancePayment();
        payment.setId("adp" + IdUtil.getSnowflake(2, 2).nextIdStr());
        payment.setOrderId(request.getOrderId());
        payment.setDriverId(request.getDriverId());
        // 计算提前付款金额
        Map<String, Object> waybillMap = normalMapper.queryWayBillInfo(orderMap.get("goods_id").toString());
        BigDecimal allFee = new BigDecimal(waybillMap.get("all_fee").toString());
        // 查询结算比例 先默认 0.2
        int amount = allFee.intValue() * 20;
        payment.setAmount(amount);
        wytAdvancePaymentMapper.insert(payment);
        return new BaseResponse("cey0000", "申请成功，等待管理员审核");
    }

    @GetMapping("/ensure-advance-payment")
    @ApiOperation(value = "提前付款申请审核通过接口")
    @Transactional(rollbackFor = Exception.class)
    public BaseResponse ensureAdvancePayment(String id) throws AppException {
        WytAdvancePayment payment = wytAdvancePaymentMapper.selectById(id);
        if (payment == null || !StringUtils.equalsIgnoreCase(payment.getStatus(), WytAdvancePayment.STATUS_ING)) {
            throw new AppException("cey1010", "数据未找到，或者已经审核完成");
        }
        // 司机油卡增加金额
        WytCurrencyPayAccountPojo accountPojo = payAccountMapper.selectById(payment.getDriverId());
        if (accountPojo == null) {
            throw new AppException("cey9999", "客户信息未找到");
        }
        accountPojo.setOilCoins(accountPojo.getOilCoins() + payment.getAmount());
        payment.setStatus(WytAdvancePayment.STATUS_SUCCESS);
        payAccountMapper.updateById(accountPojo);
        wytAdvancePaymentMapper.updateById(payment);

        return new BaseResponse("cey0000", "提前付款到油卡成功");
    }

    @PostMapping("/oil-card-withdrawal")
    @ApiOperation(value = "油卡线下提现申请")
    @Transactional(rollbackFor = Exception.class)
    public BaseResponse oilCardWithdrawal(@RequestBody OilCardWithdrawalRequest request) throws Exception {
        WytCurrencyPayAccountPojo accountPojo = payAccountMapper.selectById(request.getUserId());
        if (accountPojo == null || accountPojo.getOilCoins() == 0) {
            throw new AppException("cey9999", "未查询到用户信息，或者用户油卡金额不足");
        }

        WytOilCardOfflineWithdrawalPojo oilCardOfflineWithdrawalPojo = oilCardOfflineWithdrawalMapper.selectOne(new QueryWrapper<WytOilCardOfflineWithdrawalPojo>().eq("user_id", request.getUserId()).eq("status", "I"));
        if (oilCardOfflineWithdrawalPojo != null) {
            throw new AppException("cey1020", "存在未审核的油卡提现申请，请审核后再尝试");
        } else {
            oilCardOfflineWithdrawalPojo = new WytOilCardOfflineWithdrawalPojo();
            oilCardOfflineWithdrawalPojo.setAmount(request.getAmount().intValue() * 100);
            oilCardOfflineWithdrawalPojo.setUserId(request.getUserId());
            oilCardOfflineWithdrawalPojo.setId(IdUtil.createSnowflake(2, 10).nextIdStr());
            oilCardOfflineWithdrawalMapper.insert(oilCardOfflineWithdrawalPojo);
            return new BaseResponse("cey0000", "申请线下提现成功");
        }
    }

    @PostMapping("/ensure-oil-card-withdrawal")
    @ApiOperation(value = "通过油卡线下提现申请")
    @Transactional(rollbackFor = Exception.class)
    public BaseResponse ensureOilCardWithdrawal(@RequestBody EnsureOilCardWithdrawalRequest request) throws Exception {
        WytOilCardOfflineWithdrawalPojo pojo = oilCardOfflineWithdrawalMapper.selectById(request.getId());
        if (pojo == null || !StringUtils.equalsIgnoreCase(pojo.getStatus(), "I")) {
            throw new AppException("cey1099", "未找到提现的订单，或者订单已经被审核");
        }
        WytCurrencyPayAccountPojo accountPojo = payAccountMapper.selectById(pojo.getUserId());
        if (accountPojo == null || accountPojo.getOilCoins() < pojo.getAmount()) {
            throw new AppException("cey1089", "用户ID未找到，或者金额不足");
        }

        accountPojo.setOilCoins(accountPojo.getOilCoins() - pojo.getAmount());
        payAccountMapper.updateById(accountPojo);
        pojo.setImgPath(request.getImgPath());
        pojo.setStatus("S");
        oilCardOfflineWithdrawalMapper.updateById(pojo);
        return new BaseResponse("cey0000", "线下提现申请通过");
    }

}
